#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

namespace superio{
    #define getchar my_getchar
    const int Isize = 1<<22;
    char ibuf[Isize],*p1=ibuf,*p2=ibuf;
    inline char getchar() {return p1==p2&&(p2=(p1=ibuf)+fread(ibuf,sizeof(char),sizeof(ibuf),stdin),p1==p2)?EOF:*p1++;}

    struct{template<typename T>operator T(){
        T x=0;char f=0,c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+(c^48);c=getchar();}
        return f?-x:x;
    }}in;int stk[40],tp;
    template<typename T>void out(T x,char c=0){
        if(x<0)putchar('-'),x=-x;
        do stk[++tp]=x%10,x/=10;while(x);
        while(tp)putchar(stk[tp--]^48);
        if(c)putchar(c);
    }
}
using superio::in;
using superio::out;
using superio::getchar;

typedef long long ll;
const int N = 1005,M = 16,C = N/M+2,wg_uid = 147744151;
ll a[N][N];
int n,m,mod;

class segtree{
    public:
        ll b[C][C],pre[C][M],nxt[C][M],tr[N*4];
        void pushup(int u){tr[u] = tr[u<<1]*tr[u<<1|1]%mod;}
        void build_tr(int u,int l,int r,int x){
            if(l==r){
                tr[u] = a[x][l];
                return;
            }
            int mid = (l+r)>>1;
            build_tr(u<<1,l,mid,x);
            build_tr(u<<1|1,mid+1,r,x);
            pushup(u);
        }
        ll query_tr(int u,int l,int r,int L,int R){
            if(L>R)
                return 1;
            if(l>=L&&r<=R)
                return tr[u];
            int mid = (l+r)>>1;
            if(L<=mid&&R>mid)
                return query_tr(u<<1,l,mid,L,R)*query_tr(u<<1|1,mid+1,r,L,R)%mod;
            if(L<=mid)
                return query_tr(u<<1,l,mid,L,R);
            return query_tr(u<<1|1,mid+1,r,L,R);
        }
        void build(int x){
            build_tr(1,1,m,x);
            int len = m/M;
            for(int k=0;k<=len;k++){
                b[k][k] = 1;
                int L = k*M+1,R = min(m,(k+1)*M);
                for(int j=L;j<=R;j++)
                    b[k][k] = b[k][k]*a[x][j]%mod;
            }
            for(int k=1;k<=len;k++)
                b[k][k-1] = 1;
            for(int k=0;k<=len;k++)
                for(int j=k+1;j<=len;j++)
                    b[k][j] = b[k][j-1]*b[j][j]%mod;
            for(int k=0;k<=len;k++){
                int L = k*M+1,R = min(m,(k+1)*M);
                pre[k][0] = a[x][R];
                for(int j=R-1;j>=L;j--)
                    pre[k][R-j] = pre[k][R-j-1]*a[x][j]%mod;
            }
            for(int k=0;k<=len;k++){
                int L = k*M+1,R = min(m,(k+1)*M);
                nxt[k][0] = a[x][L];
                for(int j=L+1;j<=R;j++)
                    nxt[k][j-L] = nxt[k][j-L-1]*a[x][j]%mod;
            }
        }
        int query(int l,int r){
            int L = (l-1)/M,R = (r-1)/M;
            if(L+1>=R)
                return query_tr(1,1,m,l,r);
            return b[L+1][R-1]*pre[L][(L+1)*M-l]%mod*nxt[R][r-(R*M+1)]%mod;
        }
};

class ssegtree{
    private:
        segtree tr[N*4];

        void pushup(int u){
            for(int k=0;k<C;k++)
                for(int j=0;j<C;j++)
                    tr[u].b[k][j] = tr[u<<1].b[k][j]*tr[u<<1|1].b[k][j]%mod;
            for(int k=0;k<C;k++)
                for(int j=0;j<M;j++){
                    tr[u].pre[k][j] = tr[u<<1].pre[k][j]*tr[u<<1|1].pre[k][j]%mod;
                    tr[u].nxt[k][j] = tr[u<<1].nxt[k][j]*tr[u<<1|1].nxt[k][j]%mod;
                }
            for(int k=1;k<N*4;k++)
                tr[u].tr[k] = tr[u<<1].tr[k]*tr[u<<1|1].tr[k]%mod;
        }
    public:
        void build(int u,int l,int r){
            if(l==r){
                tr[u].build(l);
                return;
            }
            int mid = (l+r)>>1;
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
            pushup(u);
        }
        ll query(int u,int l,int r,int L,int R,int X,int Y){
            if(l>=L&&r<=R)
                return tr[u].query(X,Y);
            int mid = (l+r)>>1;
            if(L<=mid&&R>mid)
                return query(u<<1,l,mid,L,R,X,Y)*query(u<<1|1,mid+1,r,L,R,X,Y)%mod;
            if(L<=mid)
                return query(u<<1,l,mid,L,R,X,Y);
            return query(u<<1|1,mid+1,r,L,R,X,Y);
        }
}tr;

namespace sub_sb{
    #define int long long
    int b[N][N];
    int ksm(int a,int b){
        int ans = 1;
        while(b){
            if(b&1)
                ans = ans*a%mod;
            a = a*a%mod;
            b >>= 1;
        }
        return ans;
    }
    signed main(){
        for(int k=0;k<=n;k++)
            b[k][0] = a[k][0] = 1;
        for(int k=0;k<=m;k++)
            b[0][k] = a[0][k] = 1;
        for(int k=1;k<=n;k++)
            for(int j=1;j<=m;j++)
                a[k][j] = a[k][j-1]*a[k][j]%mod;
        for(int j=1;j<=m;j++)
            for(int k=1;k<=n;k++)
                a[k][j] = a[k-1][j]*a[k][j]%mod;
        for(int k=1;k<=n;k++)
            for(int j=1;j<=m;j++)
                b[k][j] = ksm(a[k][j],mod-2);
        int q = in,ans = 0;
        for(int k=1;k<=q;k++){
            int x1 = in,y1 = in,x2 = in,y2 = in;
            ans = (ans+(k^(a[x2][y2]*b[x1-1][y2]%mod*b[x2][y1-1]%mod*a[x1-1][y1-1]%mod)))%wg_uid;
        }
        out(ans);
        return 0;
    }
    #undef int
}

int main(){
    freopen("tsuki.out","r",stdin);
    freopen("tsuki.out","w",stdout);
    n = in,m = in,mod = in;
    for(int k=1;k<=n;k++)
        for(int j=1;j<=m;j++)
            a[k][j] = in;
    if(mod==998244353)
        return sub_sb::main();
    tr.build(1,1,n);
    int q = in;
    ll ans = 0;
    for(int k=1;k<=q;k++){
        int x1 = in,y1 = in,x2 = in,y2 = in;
        ans = (ans+(k^tr.query(1,1,n,x1,x2,y1,y2)))%wg_uid;
    }
    out(ans);
    return 0;
}